package de.pharmacontrol.utils;

import java.util.regex.Pattern;


public class StringValidator {
	
	private String s_str;
	
	public StringValidator() {
		setText("");
	}
	
	public StringValidator(String str) {
		setText(str.trim());
	}
	
	public void setText(String str) {
		this.s_str=str.trim();
	}
	public String getText() {
		return this.s_str;
	}
	
	/**
	 * calculate Password strength
	 * @return int
	 */
	public int getPwdStrongness(){
		return getPwdStrongness(this.s_str);
	}

	/**
	 * calculate Password strength
	 * @return int
	 */
	public int getPwdStrongness(String pwd){
		if (pwd.isEmpty())
			return 0;
		int min_ascii=(int)pwd.charAt(0);
		int max_ascii=min_ascii;
		int uniquelength=1;
		int temp;
		
		for (int i = 1; i < pwd.length();i++) {
			temp=(int)pwd.charAt(i);
			if (!pwd.substring(0,i).contains(String.valueOf(pwd.charAt(i))))
				uniquelength++;
			if (temp > max_ascii)
				max_ascii=temp;
			else if (temp < min_ascii)
				min_ascii=temp;	
		}
		// NOTE: Don't forget to comment out in production version!
//		System.out.println(min_ascii + " <-> " + max_ascii);
//		System.out.println(uniquelength);
		double strength=Math.log10(Math.pow((max_ascii-min_ascii+1),uniquelength));
		return (int) Math.round(strength);
	}

	/**
	 * calculate Password strength under password policy condition
	 * @return int
	 */
	public int getPwdStrongness( String pwd, Pattern passwdPolicy){
		if (passwdPolicy == null || passwdPolicy.matcher( pwd).matches())
			return  getPwdStrongness( pwd);
		return  0;
	}
	
	/**
	 * validate GTIN
	 * String with last checksum char
	 * @return boolean
	 */
	public boolean isValidGTIN() {
		return isValidGTIN(this.s_str);
	}
	
	/**
	 * validate GTIN <P>
	 * <P>
	 * EAN (European Article Number) check digits (administered by GS1)          <br>
	 * are calculated by summing the even position numbers and multiplying by 3, <br> 
	 * then adding the sum of the odd position numbers.                          <br>
	 * The final digit of the result is subtracted from 10                       <br>
	 * to calculate the check digit (or left as is if already zero).             <br> 
	 * For a GS1 check digit calculator and detailed documentation see           <br>
	 * http://www.gs1.org/barcodes/support/check_digit_calculator
	 * @param gtin String with last checksum char
	 * 
	 * @return isCheckDigitValid
	 */
	public boolean isValidGTIN(String gtin) {
		
		if (gtin == null ||gtin.isEmpty()){
			return false;
		}
		int factor = 3;
		int checksum = 0;
		try {
			int currentCC = Integer.parseInt(String.valueOf(gtin.charAt(gtin.length() - 1)));

			for (int i = gtin.length() - 1; i > 0; --i) {
				checksum += (Integer.parseInt(String.valueOf(gtin.charAt(i-1))) * factor);
				factor = 4 - factor; // toggle between 3 for even and 1 for odd position numbers
			}
			int realCC = ((1000 - checksum) % 10);

//			System.out.println("real checksum: " + realCC);
//			System.out.println("current checksum: " + currentCC);
			
			if (realCC == currentCC) {
				return true;
			}
//			else{
//				System.err.println("wrong last gtin char");
//			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return false;
	}

	/**
	 * validate IP address
	 * 
	 * @param iPaddress
	 * @return
	 */
	public boolean isValidIP(String sIP) {
		String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
		final Pattern IP_PATTERN = Pattern.compile( "^(?:" + _255 + "\\.){3}" + _255 + "$");
		return IP_PATTERN.matcher(sIP).matches();

	}
	
	public String incOrderID(String order){
		Pattern num=Pattern.compile("\\d");
		if (order.isEmpty() || !num.matcher(order).find()){
			return order;
		}
		StringBuilder numberStr=new StringBuilder();
		char[] charArray=order.toCharArray();

		for (int i=charArray.length-1;i>-1;--i){
			if (!Character.isDigit(charArray[i]) || i==0){
				order=order.substring(0,i+1);
				if (i==charArray.length-1){
					return order;
				}
				break;
			}
			numberStr.insert(0,charArray[i]);
		}
		long ordernr = Long.parseLong(numberStr.toString());
		ordernr++;
		if (numberStr.length()!=String.valueOf(ordernr).length()){
			return order+String.valueOf(ordernr).substring(1);
		}
	
		return order+String.valueOf(ordernr);
	}
	
	public static void main(String args[]) {
		StringValidator check = new StringValidator();
//		System.out.println("getPwdStrongness (abc) "+check.getPwdStrongness("abc"));
//		System.out.println("getPwdStrongness (gDh12) "+check.getPwdStrongness("gDh12"));
//		System.out.println("getPwdStrongness (gdh12) "+check.getPwdStrongness("gdh12"));
//		System.out.println("isValidGTIN "+check.isValidGTIN("12345678901231"));
//		System.out.println("isValidGTIN "+check.isValidGTIN("11111111111113"));
//		
//		System.out.println("ABC123 "+check.incOrderID("ABC123"));
//		System.out.println("ABC999 "+check.incOrderID("ABC999"));
//		System.out.println("AB23C23 "+check.incOrderID("AB23C23"));
//		System.out.println("2B23C23A "+check.incOrderID("2B23C23A"));
//		System.out.println("1234567890 "+check.incOrderID("1234567890"));
		
		System.out.println("aa.aa.aa.aa"+check.isValidIP("aa.aa.aa.aa"));
		System.out.println("1234567890 "+check.isValidIP("1234567890 "));
		System.out.println("1.1.1.1"+check.isValidIP("1.1.1.1"));
		System.out.println("0.0.0.00"+check.isValidIP("0.0.0.00"));
		System.out.println("255.255.255.255"+check.isValidIP("255.255.255.255"));
		System.out.println("192.0.0.1"+check.isValidIP("192.0.0.1"));
		System.out.println(" 127.0.0.255 "+check.isValidIP("127.0.0.255"));
	}

}
